package com.yx.listener;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.yx.constants.HomeConstants;
import com.yx.constatns.RabbitMQConstatns;
import com.yx.feign.api.GoodsService;
import com.yx.vo.Goods;
import com.yx.vo.GoodsType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Classname GoodsESQueueListener
 * @Date 2021/07/12 19:50
 * @Author by yx
 * @Description TODO:
 */
@Component
@Slf4j
public class GoodsTypeInsertQueueListener {

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RabbitListener(queues = RabbitMQConstatns.GOODS_TYPE_QUEUE)
    public void GoodsToES(String json, Channel channel, Message message) throws IOException {
        //1.获取routingkey
        String routingKey = message.getMessageProperties().getReceivedRoutingKey();
        log.debug("{}", json);

        switch (routingKey) {
            case "shop.goodsType.insert":
                //新增了商品类型,强制更新redis数据库中的数据
                try {
                    //1.获取锁
                    RLock lock = redissonClient.getLock(HomeConstants.HOME_GOODS_TYPE_LOCK);
                    //2.加锁 使用锁的默认时间,超时会自动续命
                    lock.lock();
                    try {
                        //缓存中没有数据,到数据库中查询
                        List<GoodsType> goodsTypeList = goodsService.getGoodsTypeList();

                        //创建一个新list集合用于存放商品类型集合,整合父子标签
                        List<GoodsType> newGoodsTypeList = new ArrayList<>();
                        // 查询并存储一级标签
                        for (GoodsType goodsType : goodsTypeList) {
                            if (goodsType.getGoodsTypePid() == -1) {
                                newGoodsTypeList.add(goodsType);
                            }
                        }

                        //查询并存储二级标签
                        for (GoodsType fatherType : newGoodsTypeList) {
                            for (GoodsType childType : goodsTypeList) {
                                if (childType.getGoodsTypePid().equals(fatherType.getId())) {
                                    // 将该子类标签存入父类标签
                                    fatherType.getChildrenList().add(childType);
                                }
                            }
                        }
                        //将查询并封装好的数剧存入redis
                        String data = JSON.toJSONString(newGoodsTypeList);

                        if (!StringUtils.isEmpty(data)) {
                            // 查询数据不为空
                            redisTemplate.opsForValue().set(HomeConstants.HOME_GOODS_TYPE_LIST_KEY, data, 10, TimeUnit.DAYS);
                        } else {
                            // 数据库中查询的数据为空,即缓存与数据库中都没有数据,此时会发生缓存穿透问题---> 存储一个空字符串解决缓存穿透问题
                            redisTemplate.opsForValue().set(HomeConstants.HOME_GOODS_TYPE_LIST_KEY, "null");

                        }
                    } finally {
                        //.释放锁
                        lock.unlock();
                    }
                    //手动ack
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                } catch (IOException e) {
                    log.error("新增商品类型向redis中更新商品类型数据出现了异常", e);
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
                }
                break;
            default:
                System.out.println("无此routingKey");
                break;
        }


    }
}
